package com.nineclock.approve.resolver.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.nineclock.approve.resolver.ProcessNodeResolver;
import com.nineclock.approve.resolver.ProcessNodeResolverFactory;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;

import java.util.ArrayList;
import java.util.List;

/**
 * 排他网关流程处理器
 */
public class ConditionNodeResolver  extends ProcessNodeResolver {
	
    @Override
    public void addFlowNodeToActiviti(Process process, JSONObject currNode, JSONObject nextNode) {

        //创建排他网关
        ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
        exclusiveGateway.setId(getNodeId(currNode));
        exclusiveGateway.setName(currNode.getStr("name"));

        process.addFlowElement(exclusiveGateway);

        //创建流程连线
        List<SequenceFlow> sfList = new ArrayList<>();
        JSONArray nodeArray = (JSONArray) currNode.get("node");

        for (int i = 0; i < nodeArray.size(); i++) {
            //创建网关到每个分支第二个节点的连线 ; 以为第一个节点是条件, 不做为节点存在 ;
            JSONArray nodes = (JSONArray) nodeArray.get(i);
            JSONObject cond = (JSONObject) nodes.get(0);//第一个节点 ---> 条件
            JSONObject node = (JSONObject) nodes.get(1); //第二个节点--------> 绘制网关, 到该节点的连接线

            //绘制网关, 到该节点(第二个节点)的连接线
            SequenceFlow flow = newSequenceFlow(process, currNode, node, cond);
            sfList.add(flow);


            //创建从网关中 , 第二个节点开始, 之后的节点;
            for (int j = 1; j < nodes.size(); j++) {

                JSONObject innerCurrNode = (JSONObject) nodes.get(j);
                JSONObject innerNextNode = null;

                if(j < nodes.size()-1){ //不是网关内的最后一个节点
                    innerNextNode = (JSONObject) nodes.get(j+1);
                }else{ //如果是网关内的最后一个节点
                    innerNextNode = nextNode;
                }

                //构建网关内部的节点对象, 添加到Process中;
                ProcessNodeResolverFactory.getInstance(innerCurrNode.getStr("type"))
                        .addFlowNodeToActiviti(process, innerCurrNode, innerNextNode);
            }
        }
        //添加连线
        exclusiveGateway.setOutgoingFlows(sfList);
    }

}